<?php

namespace slinks;

use slinks\common\UniversalClassLoader;
use slinks\core\DependencyInjection\ParameterBag\ParameterBag;
use slinks\core\SlinksContainer;
use slinks\core\DependencyInjection\Loader\Loader;
use slinks\core\DependencyInjection\Loader\LoaderResolver;
use slinks\core\DependencyInjection\Loader\XmlFileLoader;
use slinks\core\DependencyInjection\Loader\YamlFileLoader;
use slinks\core\DependencyInjection\Loader\IniFileLoader;
use slinks\core\DependencyInjection\Loader\PhpFileLoader;
use slinks\core\DependencyInjection\Loader\ClosureLoader;
use slinks\core\DependencyInjection\Loader\DelegatingLoader;
use slinks\core\DependencyInjection\ContainerInterface;
use slinks\core\DependencyInjection\Dumper\PhpDumper;
use slinks\core\DependencyInjection\ContainerBuilder;

/**
 * 
 * @author Navid Mitchell
 *
 */
class Slinks {

    private static $instance;
    private $application = null;
    private $debug = false;
    private $cacheDirectory = null;
    private $autoRegisterNamespace=true;
    private $fileSuffix = '.config.xml';

    private function __construct() {
        require_once 'autoload.php';
    }

    /**
     * Returns the singleton instance of this object
     * @return Slinks
     */
    public static function getInstance() {
        // if not yet intialized
        if (!isset(self::$instance)) {
            self::$instance = new Slinks();
        }
        return self::$instance;
    }

    /**
     * Initialize a Slinks container with the given configuration file and container id.
     *
     * @param string $applicationConfigDir the directory containing the application config file.
     *                The file must follow standard naming conventions {applicationName}fileSuffix. 
     *                File suffix defaults to .config.xml EX: myApplication.config.xml
     * @param array $parameters the parameters to initialize the application with.
     */
    public function initialize($applicationConfigDir, array $parameters=array()) {

        $cacheDir = ( isSet($this->cacheDirectory) ? $this->cacheDirectory : __DIR__ . DIRECTORY_SEPARATOR . 'cache');
        
        if ($this->application != null) {
            return $this->application;
        } else {
            return $this->application = 
                    new SlinksContainer($applicationConfigDir,
                                        $cacheDir,
                                        new ParameterBag(array_merge($parameters, 
                                                         array('slinks.cache.dir' => $cacheDir,
                                                               'slinks.config.root.dir' => $applicationConfigDir,
                                                               'slinks.debug.enabled' => $this->debug))),
                                        $this->debug,
                                        $this->autoRegisterNamespace,
                                        $this->fileSuffix);
        }
    }

    public function getApplicationContainer(){
        return $this->application;
    }
    
    /**
     * Gets a service.
     *
     * If a service is both defined through a setService() method and
     * with a set*Service() method, the former has always precedence.
     *
     * @param  string $id The service identifier
     *
     * @return object The associated service
     *
     * @throw InvalidArgumentException if the service is not defined
     */
    public function getService($id) {
        return $this->application->get($id);
    }

    /**
     * Returns true if the given service is defined.
     *
     * @param  string  $id      The service identifier
     *
     * @return Boolean true if the service is defined, false otherwise
     */
    public function hasService($name) {
        return $this->application->has($id);
    }

    /**
     * @param Boolean $debug true to enable debugging false to disable.
     */
    public function setDebugEnabled($debug) {
        $this->debug = $debug;
    }

    public function setCacheDirectory($directory) {
        $this->cacheDirectory = $directory;
    }

    public function getAutoRegisterNamespace() {
        return $this->autoRegisterNamespace;
    }

    public function setAutoRegisterNamespace($autoRegisterNamespace) {
        $this->autoRegisterNamespace = $autoRegisterNamespace;
    }

    public function getFileSuffix() {
        return $this->fileSuffix;
    }

    public function setFileSuffix($fileSuffix) {
        $this->fileSuffix = $fileSuffix;
    }

}

